#include <iostream>
#include <memory>

using namespace std;

// demo1: connection and disconnection
struct destination
{
};
struct connection
{
};
connection connect(destination *pd)
{
    cout << "start connecting." << endl;
    return connection();
}

void disconnect(connection c)
{
    cout << "disconnecting." << endl;
}

void conn(destination &d)
{
    cout << "directly manage connection." << endl;
    connection c = connect(&d);
    // but not disconnect
    cout << endl;
}

void end_connection(connection *p)
{
    disconnect(*p);
}

void shared_conn(destination &d)
{
    cout << "shared manage connection." << endl;
    connection c = connect(&d);
    shared_ptr<connection> p(&c, end_connection);
    // but also not disconnect
    cout << endl;
}

// demo2: file open and close

#include <fstream>
#include <string>
void process_file(const string &filename)
{
    cout << "directly start process file." << endl;
    ifstream in(filename);
    // forget to close file
    cout << "forget to close file." << endl;
}

void shared_process_file(const string &filename)
{
    cout << "shared start process file." << endl;
    shared_ptr<ifstream> p(new ifstream(filename), [](ifstream *p)
                           { p->close(); cout << "Great! I haved close file."; });
    // forget to close file
    cout << endl;
}

// demo3: open file like Python.

// 定义文件打开模式
enum class FileMode
{
    Read,
    Write,
    Append,
    ReadWrite
};

// 自定义删除器
struct FileDeleter
{
    void operator()(fstream *file)
    {
        if (file)
        {
            file->close();
            delete file;
            file = nullptr;
            cout << "Great! I have closed the file." << endl;
        }
    }
};

// 类似于 Python 的 open 函数
shared_ptr<fstream> open(const string &filename, FileMode mode)
{
    fstream *file = nullptr;

    switch (mode)
    {
    case FileMode::Read:
        file = new fstream(filename, ios_base::in);
        break;
    case FileMode::Write:
        file = new fstream(filename, ios_base::out | ios_base::trunc);
        break;
    case FileMode::Append:
        file = new fstream(filename, ios_base::out | ios_base::app);
        break;
    case FileMode::ReadWrite:
        file = new fstream(filename, ios_base::in | ios_base::out);
        break;
    default:
        throw invalid_argument("Invalid mode");
    }

    if (!file->is_open())
    {
        delete file;
        throw runtime_error("Failed to open file: " + filename);
    }

    return shared_ptr<fstream>(file, FileDeleter());
}
int main()
{
    // demo1
    destination d;
    conn(d);
    shared_conn(d);
    cout << "---" << endl;

    // demo2
    process_file("../data/names.txt");
    shared_process_file("../data/names.txt");

    // demo3
    try
    {
        // 打开文件进行读写
        string filename = "../data/names.txt";
        auto fp = open(filename, FileMode::ReadWrite);

        // 读取文件内容
        // string line;
        // while (getline(*fp, line))
        // {
        //     cout << line << endl;
        // }

        // 写入文件内容
        if (fp->good()) // 检查文件流状态
        {
            fp->seekp(0, ios_base::end); // 移动到文件末尾
            fp->write("New line\n", 9);  // 写入新行
            fp->flush();                 // 刷新缓冲区
        }
        else
        {
            cerr << "Error: File stream is not in a good state." << endl;
        }
    }
    catch (const exception &e)
    {
        cerr << "Error: " << e.what() << endl;
    }
}